home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include "o.h"
-
- extern int data_seg_idx;
- extern dword data_offset;
-
- extern THREAD_T threads[2][4];
-
- void fix_insert( int, int, int, long, int, int, int, int, int );
-
- int fix_compare( rec_1, rec_2 )
- FIX_T *rec_1;
- FIX_T *rec_2;
- {
- if ( rec_1->seg_idx > rec_2->seg_idx ) {
- return( LEFT );
- } else {
- if ( rec_1->seg_idx < rec_2->seg_idx ) {
- return( RIGHT );
- } else {
- if ( rec_1->dat_offset > rec_2->dat_offset ) {
- return( LEFT );
- } else {
- if ( rec_1->dat_offset < rec_2->dat_offset ) {
- return( RIGHT );
- } else {
- if ( rec_1->offset > rec_2->offset ) {
- return( LEFT );
- } else {
- if ( rec_1->offset < rec_2->offset ) {
- return( RIGHT );
- } else {
- return( EQUAL );
- }
- }
- }
- }
- }
- }
- }
-
- void fix_insert( offset, relate, form, displacement, a_mode, a_index,
- b_mode, b_index, extension )
- int offset;
- int relate;
- int form;
- long displacement;
- int a_mode;
- int a_index;
- int b_mode;
- int b_index;
- int extension;
- {
- FIX_T *fixup_rec;
-
- fixup_rec = (FIX_T *)o_malloc( sizeof(FIX_T) );
- fixup_rec->seg_idx = data_seg_idx;
- fixup_rec->dat_offset = data_offset;
- fixup_rec->offset = offset;
- fixup_rec->relate = relate;
- fixup_rec->form = form;
- fixup_rec->displacement = displacement;
- fixup_rec->a_mode = a_mode; /* Mode of frame */
- fixup_rec->a_index = a_index; /* Index of frame */
- fixup_rec->b_mode = b_mode; /* Mode of target */
- fixup_rec->b_index = b_index; /* Index of target */
- fixup_rec->extended = extension;
-
- #ifdef DEBUG
- printf("FIXUP:%04X:%08lX:%04X displacement=%08lX\n",
- data_seg_idx,data_offset,offset, displacement );
- #endif
- if ( form == OFFSET || form == BASE || form == LOADOFF ) {
- fixup_rec->word_sized = TRUE;
- } else {
- fixup_rec->word_sized = FALSE;
- }
-
- insert( (char *)fixup_rec, fix_tree, TC fix_compare );
- }
-
- int decode_fixup( relate, size, form, offset, extension )
- int relate; /* mode 0=self rel, 1=segment rel */
- int size; /* zero */
- int form; /* LOC value [0-4] */
- int offset; /* offset of data item */
- int extension;
- {
- int length;
- int fix;
- int thread;
- int a_mode; /* Mode of Frame */
- int a_index; /* Index of Frame */
- int b_mode; /* Mode of Target */
- int b_index; /* Index of Target */
- int fbit;
- int tbit;
- int pbit;
- dword displacement;
- int extended;
-
- extended = FALSE;
-
- fix = get_byte();
-
- length = 1;
- fbit = ( fix & 0x80 ) >> 7; /* F-bit field */
- a_mode = ( fix & 0x70 ) >> 4; /* frame index */
- if ( fbit == 1 ) {
- /* Reference a previously loaded thread fixup for location */
- thread = ( a_mode & 0x03 );
- a_index = threads[1][thread].index; /* mode is a thread # */
- a_mode = threads[1][thread].mode;
- } else {
- /* otherwise, frame is explicitly specified */
- if ( a_mode < 4 ) { /* mode is not a thread # */
- length += get_index( &a_index );
- }
- }
- tbit = ( fix & 0x08 ) >> 3; /* T-bit field */
- thread = ( fix & 0x07 );
- pbit = ( thread & 0x04 ) >> 2; /* P-bit field */
- b_mode = ( thread & 0x03 ); /* Target mode */
- if ( tbit == 1 ) {
- b_index = threads[0][b_mode].index; /* mode is a thread # */
- b_mode = threads[0][b_mode].mode & 0x03;
- } else {
- length += get_index( &b_index ); /* mode is not a thread # */
- }
-
- if ( size != 0 && extension ) { /* size is always 0 for 16bit MS langs */
- extended = TRUE;
- }
-
- if ( pbit == 0 ) {
- displacement = (dword)get_int();
- length += 2;
- if ( extended ) {
- displacement += (dword)get_byte() << 16;
- displacement += (dword)get_byte() << 24;
- length += 2;
- }
- } else {
- displacement = 0L;
- }
-
- if ( a_mode == 5 ) { /* don't process this type of fixupp */
- a_mode = b_mode;
- a_index = b_index;
- }
-
- fix_insert( offset, relate, form, displacement, a_mode, a_index,
- b_mode, b_index, extended );
- return( length );
- }
-
-
- void fixupp( length, extension )
- word length;
- int extension;
- {
- uchar type; /* First byte of a FIXUPP packet */
- int kind;
- int thread;
- int locat;
- int relate;
- int size;
- int form;
- int offset;
- int mode;
- int index;
-
- --length; /* Subtract 1 for checksum */
-
- while ( length ) {
- type = get_byte();
- --length;
- if ( type & 0x80 ) {
- /*
- ** True FixUp aka Explicit FixUp Record
- */
- --length;
- locat = ((int)type << 8) + get_byte();
- relate = ( locat & 0x4000 ) >> 14; /* mode */
- size = ( locat & 0x2000 ) >> 13; /* zero */
- form = ( locat & 0x1C00 ) >> 10; /* LOC [0,4] */
- offset = ( locat & 0x03FF );
-
- length -= decode_fixup( relate, size, form, offset, extension );
- } else {
- /*
- ** Thread FixUp
- */
- kind = ( type & 0x40 ) >> 6;
- mode = ( type & 0x1C ) >> 2;
- thread = ( type & 0x03 );
- threads[kind][thread].mode = mode;
- if ( mode == 0 || thread < 4 ) {
- length -= get_index( &index );
- threads[kind][thread].index = index;
- }
- }
- }
- }
-